Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Node / ReticulumProjects / MeshChatX.git / files / tests / frontend / MarkdownRenderer.test.js

Displaying Raw • Download


tests/frontend/MarkdownRenderer.test.js bce42bcdce0e7d2c6d78228e864a4cd1d974cc82 (bce42bcd) Text, 26.51 KB

Tff7b72import Tb4b4b4{ Te6edf3describeTb4b4b4, Te6edf3itTb4b4b4, Te6edf3expect Tb4b4b4} Tff7b72from Ta5d6ff"vitest"Tb4b4b4;
Tff7b72import Te6edf3MarkdownRenderer Tff7b72from Ta5d6ff"@/js/MarkdownRenderer"Tb4b4b4;

Te6edf3describeTb4b4b4(Ta5d6ff"MarkdownRenderer.js"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3describeTb4b4b4(Ta5d6ff"render (ConversationViewer / message bodies)"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3itTb4b4b4(Ta5d6ff"escapes leading greater-than so blockquote regex does not apply (documented behaviour)"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff"> quoted line\n\nNormal paragraph."Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"> quoted line"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"Normal paragraph"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"blockquote"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3describeTb4b4b4(Ta5d6ff"render"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3itTb4b4b4(Ta5d6ff"renders basic text correctly"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3expectTb4b4b4(Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff"Hello"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"Hello"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"renders bold text correctly"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff"**Bold**"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<strong>Bold</strong>"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"renders italic text correctly"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff"*Italic*"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<em>Italic</em>"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"renders underscore italic when delimiters are word boundaries"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff"this is _italic_ text"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"this is <em>italic</em> text"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"renders bold and italic text correctly"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff"***Bold and Italic***"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<strong><em>Bold and Italic</em></strong>"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"renders headers correctly"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3expectTb4b4b4(Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff"# Header 1"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<h1"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff"## Header 2"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<h2"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff"### Header 3"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<h3"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"renders inline code correctly"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff"`code`"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<code"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"code"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"keeps snake_case intact inside inline and double-backtick code"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff"Uses `local_hops_delta` and ``rpc_key``."Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"local_hops_delta"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"rpc_key"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<em>hops</em>"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"`local_hops_delta`"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"keeps underscores intact in long https links"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3url Tff7b72= Ta5d6ff"https://github.com/Quad4-Software/MeshChatX/src/branch/dev/docs/meshchatx_on_raspberry_pi.md"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff`Ta5d6ffvisit Tffd700${Te6edf3urlTffd700}Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff`Ta5d6ffhref="Tffd700${Te6edf3urlTffd700}Ta5d6ff"Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Te6edf3urlTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<em>on</em>"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<em>raspberry</em>"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"renders fenced code blocks correctly"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff"```python\nprint('hello')\n```"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<pre"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<code"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"language-python"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"print(&#039;hello&#039;)"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"handles paragraphs correctly"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff"Para 1\n\nPara 2"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<p"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"Para 1"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"Para 2"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"does not treat intraword underscores as italic markdown"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff"snake_case_identifier should remain plain"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"snake_case_identifier should remain plain"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<em>case</em>"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"keeps underscore-heavy urls intact while still rendering links"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3url Tff7b72=
Ta5d6ff"https://example.com/docs/meshchatx_on_raspberry_pi.md?file=meshchatx_on_raspberry_pi.md#meshchatx_on_raspberry_pi"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff`Ta5d6ffsee Tffd700${Te6edf3urlTffd700}Ta5d6ff nowTa5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff`Ta5d6ffhref="Tffd700${Te6edf3urlTffd700}Ta5d6ff"Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Te6edf3urlTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<em>on</em>"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<em>raspberry</em>"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"renders multiple urls in one line without corruption"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3a Tff7b72= Ta5d6ff"https://example.com/docs/meshchatx_on_pi.md"Tb4b4b4;
Tff7b72const Te6edf3b Tff7b72= Ta5d6ff"https://example.com/plain"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff`Ta5d6fflinks: Tffd700${Te6edf3aTffd700}Ta5d6ff and Tffd700${Te6edf3bTffd700}Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff`Ta5d6ffhref="Tffd700${Te6edf3aTffd700}Ta5d6ff"Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff`Ta5d6ffhref="Tffd700${Te6edf3bTffd700}Ta5d6ff"Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Tb4b4b4(Te6edf3resultTb4b4b4.Te6edf3matchTb4b4b4(Ta5d6ff/<a href=/gTb4b4b4) Tff7b72|| Tb4b4b4[Tb4b4b4]Tb4b4b4)Tb4b4b4.Te6edf3lengthTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"trims trailing punctuation around links while keeping display punctuation"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff"Check (https://example.com/path_(v1)), and continue."Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff'href="https://example.com/path_(v1)"'Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"</a>), and continue."Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"supports encoded chars and balanced parentheses in link path"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3url Tff7b72= Ta5d6ff"https://example.com/docs/file%5Fname_(v1).md"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff`Ta5d6ffopen Tffd700${Te6edf3urlTffd700}Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff`Ta5d6ffhref="Tffd700${Te6edf3urlTffd700}Ta5d6ff"Ta5d6ff`Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"keeps escaped entities in query string links"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3url Tff7b72= Ta5d6ff"https://example.com/search?q=a&amp;lang=en"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff`Ta5d6fflookup Tffd700${Te6edf3urlTffd700}Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff'href="https://example.com/search?q=a&amp;amp;lang=en"'Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"https://example.com/search?q=a&amp;amp;lang=en"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"handles links at line boundaries with newline conversion"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3url Tff7b72= Ta5d6ff"https://example.com/meshchatx_on_pi.md"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff`Tffd700${Te6edf3urlTffd700}Ta5d6ff\nTa5d6ffnext lineTa5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff`Ta5d6ffhref="Tffd700${Te6edf3urlTffd700}Ta5d6ff"Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<br>next line"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"mixes underscore markdown with underscore urls safely"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3url Tff7b72= Ta5d6ff"https://example.com/meshchatx_on_raspberry_pi.md"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Ta5d6ff`Ta5d6ff_label_ Tffd700${Te6edf3urlTffd700}Ta5d6ff _tail_Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<em>label</em>"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<em>tail</em>"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff`Ta5d6ffhref="Tffd700${Te6edf3urlTffd700}Ta5d6ff"Ta5d6ff`Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<em>on</em>"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"escapes pre-rendered html input safely instead of nesting raw anchors"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3preRendered Tff7b72= Ta5d6ff'<p><a href="https://example.com/path_(v1)">https://example.com/path_(v1)</a></p>'Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3preRenderedTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"&lt;p&gt;"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"&lt;a href=&quot;"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<script"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3describeTb4b4b4(Ta5d6ff"security: XSS prevention (MarkdownRenderer output is v-html in ConversationMessageEntry)"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3itTb4b4b4(Ta5d6ff"escapes script tags"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3malformed Tff7b72= Ta5d6ff"<script>alert('xss')</script>"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3malformedTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<script>"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"&lt;script&gt;"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"escapes onerror attributes in images"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3malformed Tff7b72= Ta5d6ff'<img src="x" onerror="alert(1)">'Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3malformedTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<img"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"&lt;img"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"onerror=&quot;alert(1)&quot;"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"escapes html in code blocks"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3malformed Tff7b72= Ta5d6ff"```\n<script>alert(1)</script>\n```"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3malformedTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"&lt;script&gt;"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"escapes html in inline code"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3malformed Tff7b72= Ta5d6ff"`<script>alert(1)</script>`"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3malformedTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"&lt;script&gt;"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3describeTb4b4b4(Ta5d6ff"reticulum links"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3itTb4b4b4(Ta5d6ff"detects nomadnet:// links with hash and path"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3text Tff7b72= Ta5d6ff"check this out: nomadnet://1dfeb0d794963579bd21ac8f153c77a4:/page/index.mu"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff'data-nomadnet-url="1dfeb0d794963579bd21ac8f153c77a4:/page/index.mu"'Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"nomadnet://1dfeb0d794963579bd21ac8f153c77a4:/page/index.mu"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"detects bare hash and path links as nomadnet"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3text Tff7b72= Ta5d6ff"node is at 1dfeb0d794963579bd21ac8f153c77a4:/page/index.mu"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff'data-nomadnet-url="1dfeb0d794963579bd21ac8f153c77a4:/page/index.mu"'Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"1dfeb0d794963579bd21ac8f153c77a4:/page/index.mu"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"keeps Nomad backtick parameters inside conversation links"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3text Tff7b72=
Ta5d6ff"read 9ce92808be498e9e05590ff27cbfdfe4:/page/forum/thread.mu`cat=general|thread=critical-security-update-rns-139-fixes-severe-rnsh-security-flaw"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(
Ta5d6ff'data-nomadnet-url="9ce92808be498e9e05590ff27cbfdfe4:/page/forum/thread.mu`cat=general|thread=critical-security-update-rns-139-fixes-severe-rnsh-security-flaw"'
Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toMatchTb4b4b4(Ta5d6ff/thread\.mu<\/a>`cat=/Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"detects nomadnet:// links with just hash"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3text Tff7b72= Ta5d6ff"nomadnet://1dfeb0d794963579bd21ac8f153c77a4"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff'data-nomadnet-url="1dfeb0d794963579bd21ac8f153c77a4:/page/index.mu"'Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"does not detect bare hash as lxmf without prefix"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3text Tff7b72= Ta5d6ff"send to 1dfeb0d794963579bd21ac8f153c77a4"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"lxmf-link"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"1dfeb0d794963579bd21ac8f153c77a4"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"detects lxmf: prefixed hash as lxmf link"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3text Tff7b72= Ta5d6ff"send to lxmf:1dfeb0d794963579bd21ac8f153c77a4"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff'class="lxmf-link'Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff'data-lxmf-address="1dfeb0d794963579bd21ac8f153c77a4"'Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"does not detect invalid hashes"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3text Tff7b72= Ta5d6ff"not-a-hash:/page/index.mu"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"nomadnet-link"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"lxmf-link"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3describeTb4b4b4(Ta5d6ff"fuzzing: stability testing"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3generateRandomString Tff7b72= Tb4b4b4(Te6edf3lengthTb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3chars Tff7b72=
Ta5d6ff"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}|;':\",./<>?`~ \n\r\t"Tb4b4b4;
Tff7b72let Te6edf3result Tff7b72= Ta5d6ff""Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72let Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< Te6edf3lengthTb4b4b4; Te6edf3iTff7b72++Tb4b4b4) Tb4b4b4{
Te6edf3result Tff7b72+= Te6edf3charsTb4b4b4.Te6edf3charAtTb4b4b4(Tffa657MathTb4b4b4.Te6edf3floorTb4b4b4(Tffa657MathTb4b4b4.Te6edf3randomTb4b4b4(Tb4b4b4) Tff7b72* Te6edf3charsTb4b4b4.Te6edf3lengthTb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3resultTb4b4b4;
Tb4b4b4}Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"handles random inputs without crashing (100 iterations)"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72let Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< T79c0ff100Tb4b4b4; Te6edf3iTff7b72++Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3randomText Tff7b72= Te6edf3generateRandomStringTb4b4b4(Tffa657MathTb4b4b4.Te6edf3floorTb4b4b4(Tffa657MathTb4b4b4.Te6edf3randomTb4b4b4(Tb4b4b4) Tff7b72* T79c0ff1000Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3randomTextTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toThrowTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"handles deeply nested or complex markdown patterns without crashing"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3complex Tff7b72= Ta5d6ff"# "Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff100Tb4b4b4) Tff7b72+ Ta5d6ff"**"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff100Tb4b4b4) Tff7b72+ Ta5d6ff"```"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff100Tb4b4b4) Tff7b72+ Ta5d6ff"```\n"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff10Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3complexTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toThrowTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"handles large inputs correctly (1MB of random text)"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3largeText Tff7b72= Te6edf3generateRandomStringTb4b4b4(T79c0ff1024 Tff7b72* T79c0ff1024Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3start Tff7b72= Tffa657DateTb4b4b4.Te6edf3nowTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3largeTextTb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3end Tff7b72= Tffa657DateTb4b4b4.Te6edf3nowTb4b4b4(Tb4b4b4)Tb4b4b4;

Te6edf3expectTb4b4b4(Tff7b72typeof Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff"string"Tb4b4b4)Tb4b4b4;
T8b949e// Random 1MB includes many backticks; placeholder restore must stay near-linear.
Te6edf3expectTb4b4b4(Te6edf3end Tff7b72- Te6edf3startTb4b4b4)Tb4b4b4.Te6edf3toBeLessThanTb4b4b4(T79c0ff2000Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"handles potential ReDoS patterns (repeated separators)"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
T8b949e// Test patterns that often cause ReDoS in poorly written markdown parsers (can never be too careful, especially on public testnets)
Tff7b72const Te6edf3redosPatterns Tff7b72= Tb4b4b4[
Ta5d6ff"*"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff10000Tb4b4b4)Tb4b4b4, T8b949e// Long string of bold markers
Ta5d6ff"#"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff10000Tb4b4b4)Tb4b4b4, T8b949e// Long string of header markers
Ta5d6ff"`"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff10000Tb4b4b4)Tb4b4b4, T8b949e// Long string of backticks
Ta5d6ff" "Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff10000Tb4b4b4) Tff7b72+ Ta5d6ff"\n"Tb4b4b4, T8b949e// Long string of whitespace
Ta5d6ff"[]("Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff5000Tb4b4b4)Tb4b4b4, T8b949e// Unclosed links (if we added them)
Ta5d6ff"** "Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff5000Tb4b4b4)Tb4b4b4, T8b949e// Bold marker followed by space repeated
Tb4b4b4]Tb4b4b4;

Te6edf3redosPatternsTb4b4b4.Te6edf3forEachTb4b4b4(Tb4b4b4(Te6edf3patternTb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3start Tff7b72= Tffa657DateTb4b4b4.Te6edf3nowTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3patternTb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3end Tff7b72= Tffa657DateTb4b4b4.Te6edf3nowTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3end Tff7b72- Te6edf3startTb4b4b4)Tb4b4b4.Te6edf3toBeLessThanTb4b4b4(T79c0ff100Tb4b4b4)Tb4b4b4; T8b949e// Should be very fast
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"handles unicode homoglyphs and special characters without interference"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3homoglyphs Tff7b72= Tb4b4b4[
Ta5d6ff"**bold**"Tb4b4b4,
Ta5d6ff"∗∗notbold∗∗"Tb4b4b4, T8b949e// unicode asterisks
Ta5d6ff"# header"Tb4b4b4,
Ta5d6ff"# not header"Tb4b4b4, T8b949e// fullwidth hash
Ta5d6ff"`code`"Tb4b4b4,
Ta5d6ff"`notcode`"Tb4b4b4, T8b949e// fullwidth backtick
Tb4b4b4]Tb4b4b4;
Te6edf3homoglyphsTb4b4b4.Te6edf3forEachTb4b4b4(Tb4b4b4(Te6edf3textTb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Tff7b72typeof Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff"string"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"fuzzing: full unicode code points do not crash render or strip"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72for Tb4b4b4(Tff7b72let Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< T79c0ff200Tb4b4b4; Te6edf3iTff7b72++Tb4b4b4) Tb4b4b4{
Tff7b72let Te6edf3s Tff7b72= Ta5d6ff""Tb4b4b4;
Tff7b72const Te6edf3len Tff7b72= Tffa657MathTb4b4b4.Te6edf3floorTb4b4b4(Tffa657MathTb4b4b4.Te6edf3randomTb4b4b4(Tb4b4b4) Tff7b72* T79c0ff900Tb4b4b4)Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72let Te6edf3j Tff7b72= T79c0ff0Tb4b4b4; Te6edf3j Tff7b72< Te6edf3lenTb4b4b4; Te6edf3jTff7b72++Tb4b4b4) Tb4b4b4{
Te6edf3s Tff7b72+= Tffa657StringTb4b4b4.Te6edf3fromCharCodeTb4b4b4(Tffa657MathTb4b4b4.Te6edf3floorTb4b4b4(Tffa657MathTb4b4b4.Te6edf3randomTb4b4b4(Tb4b4b4) Tff7b72* T79c0ff65536Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Te6edf3expectTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3sTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toThrowTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Te6edf3MarkdownRendererTb4b4b4.Te6edf3stripTb4b4b4(Te6edf3sTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toThrowTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3r Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3sTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3rTb4b4b4.Te6edf3toLowerCaseTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<script"Tb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"handles malformed or unclosed markdown tags gracefully"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3malformed Tff7b72= Tb4b4b4[
Ta5d6ff"**bold"Tb4b4b4,
Ta5d6ff"```python\nprint(1)"Tb4b4b4,
Ta5d6ff"#header"Tb4b4b4, T8b949e// no space
Ta5d6ff"`code"Tb4b4b4,
Ta5d6ff"___triple"Tb4b4b4,
Ta5d6ff"**bold*italic**"Tb4b4b4,
Ta5d6ff"***bolditalic**"Tb4b4b4,
Tb4b4b4]Tb4b4b4;
Te6edf3malformedTb4b4b4.Te6edf3forEachTb4b4b4(Tb4b4b4(Te6edf3textTb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3expectTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toThrowTb4b4b4(Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"underscore-heavy fuzz input does not create unbalanced emphasis tags"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3randomUnderscoreText Tff7b72= Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3parts Tff7b72= Tb4b4b4[
Ta5d6ff"_"Tb4b4b4,
Ta5d6ff"__"Tb4b4b4,
Ta5d6ff"___"Tb4b4b4,
Ta5d6ff"snake_case"Tb4b4b4,
Ta5d6ff"meshchatx_on_pi"Tb4b4b4,
Ta5d6ff" "Tb4b4b4,
Ta5d6ff"text"Tb4b4b4,
Ta5d6ff"https://example.com/meshchatx_on_pi.md"Tb4b4b4,
Tb4b4b4]Tb4b4b4;
Tff7b72let Te6edf3out Tff7b72= Ta5d6ff""Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72let Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< T79c0ff200Tb4b4b4; Te6edf3iTff7b72++Tb4b4b4) Tb4b4b4{
Te6edf3out Tff7b72+= Te6edf3partsTb4b4b4[Tffa657MathTb4b4b4.Te6edf3floorTb4b4b4(Tffa657MathTb4b4b4.Te6edf3randomTb4b4b4(Tb4b4b4) Tff7b72* Te6edf3partsTb4b4b4.Te6edf3lengthTb4b4b4)Tb4b4b4]Tb4b4b4;
Tb4b4b4}
Tff7b72return Te6edf3outTb4b4b4;
Tb4b4b4}Tb4b4b4;
Tff7b72for Tb4b4b4(Tff7b72let Te6edf3i Tff7b72= T79c0ff0Tb4b4b4; Te6edf3i Tff7b72< T79c0ff50Tb4b4b4; Te6edf3iTff7b72++Tb4b4b4) Tb4b4b4{
Tff7b72const Te6edf3rendered Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3randomUnderscoreTextTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3opensEm Tff7b72= Tb4b4b4(Te6edf3renderedTb4b4b4.Te6edf3matchTb4b4b4(Ta5d6ff/<em>/gTb4b4b4) Tff7b72|| Tb4b4b4[Tb4b4b4]Tb4b4b4)Tb4b4b4.Te6edf3lengthTb4b4b4;
Tff7b72const Te6edf3closesEm Tff7b72= Tb4b4b4(Te6edf3renderedTb4b4b4.Te6edf3matchTb4b4b4(Ta5d6ff/<\/em>/gTb4b4b4) Tff7b72|| Tb4b4b4[Tb4b4b4]Tb4b4b4)Tb4b4b4.Te6edf3lengthTb4b4b4;
Tff7b72const Te6edf3opensStrong Tff7b72= Tb4b4b4(Te6edf3renderedTb4b4b4.Te6edf3matchTb4b4b4(Ta5d6ff/<strong>/gTb4b4b4) Tff7b72|| Tb4b4b4[Tb4b4b4]Tb4b4b4)Tb4b4b4.Te6edf3lengthTb4b4b4;
Tff7b72const Te6edf3closesStrong Tff7b72= Tb4b4b4(Te6edf3renderedTb4b4b4.Te6edf3matchTb4b4b4(Ta5d6ff/<\/strong>/gTb4b4b4) Tff7b72|| Tb4b4b4[Tb4b4b4]Tb4b4b4)Tb4b4b4.Te6edf3lengthTb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3opensEmTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Te6edf3closesEmTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3opensStrongTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Te6edf3closesStrongTb4b4b4)Tb4b4b4;
Tb4b4b4}
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3describeTb4b4b4(Ta5d6ff"isSingleEmojiMessage"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3itTb4b4b4(Ta5d6ff"is true for one emoji and false for text or multiple emojis"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3expectTb4b4b4(Te6edf3MarkdownRendererTb4b4b4.Te6edf3isSingleEmojiMessageTb4b4b4(Ta5d6ff"\u{1F600}"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3MarkdownRendererTb4b4b4.Te6edf3isSingleEmojiMessageTb4b4b4(Ta5d6ff" \u{1F600} "Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3MarkdownRendererTb4b4b4.Te6edf3isSingleEmojiMessageTb4b4b4(Ta5d6ff"**\u{1F600}**"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3MarkdownRendererTb4b4b4.Te6edf3isSingleEmojiMessageTb4b4b4(Ta5d6ff"\u{1F600}\u{1F600}"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3MarkdownRendererTb4b4b4.Te6edf3isSingleEmojiMessageTb4b4b4(Ta5d6ff"hi"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3MarkdownRendererTb4b4b4.Te6edf3isSingleEmojiMessageTb4b4b4(Ta5d6ff"\u{1F600} a"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72falseTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"treats ZWJ family and skin tone as a single emoji"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3expectTb4b4b4(Te6edf3MarkdownRendererTb4b4b4.Te6edf3isSingleEmojiMessageTb4b4b4(Ta5d6ff"\u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3MarkdownRendererTb4b4b4.Te6edf3isSingleEmojiMessageTb4b4b4(Ta5d6ff"\u{1F44D}\u{1F3FD}"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Tff7b72trueTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3describeTb4b4b4(Ta5d6ff"strip"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3itTb4b4b4(Ta5d6ff"strips markdown correctly"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3md Tff7b72= Ta5d6ff"# Header\n**Bold** *Italic* `code` ```\nblock\n```"Tb4b4b4;
Tff7b72const Te6edf3stripped Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3stripTb4b4b4(Te6edf3mdTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3strippedTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"Header"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3strippedTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"Bold"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3strippedTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"Italic"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3strippedTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"code"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3strippedTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"[Code Block]"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3strippedTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"# "Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3strippedTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"**"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3strippedTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"` "Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"strip removes underscore italics but keeps intraword underscores"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3input Tff7b72= Ta5d6ff"before _italic_ after and snake_case_word"Tb4b4b4;
Tff7b72const Te6edf3stripped Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3stripTb4b4b4(Te6edf3inputTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3strippedTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"before italic after"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3strippedTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"snake_case_word"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3strippedTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"_italic_"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"strip handles null and undefined without throwing"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3expectTb4b4b4(Te6edf3MarkdownRendererTb4b4b4.Te6edf3stripTb4b4b4(Tff7b72nullTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff""Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3MarkdownRendererTb4b4b4.Te6edf3stripTb4b4b4(Tff7b72undefinedTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff""Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"strip handles ReDoS-prone patterns without hanging"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3start Tff7b72= Tffa657DateTb4b4b4.Te6edf3nowTb4b4b4(Tb4b4b4)Tb4b4b4;
Te6edf3MarkdownRendererTb4b4b4.Te6edf3stripTb4b4b4(Ta5d6ff"*"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff5000Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3MarkdownRendererTb4b4b4.Te6edf3stripTb4b4b4(Ta5d6ff"`"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff5000Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3MarkdownRendererTb4b4b4.Te6edf3stripTb4b4b4(Ta5d6ff"# "Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff2000Tb4b4b4)Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Tffa657DateTb4b4b4.Te6edf3nowTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3startTb4b4b4)Tb4b4b4.Te6edf3toBeLessThanTb4b4b4(T79c0ff200Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"strip keeps intraword underscores intact"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3url Tff7b72= Ta5d6ff"https://github.com/Quad4-Software/MeshChatX/src/branch/dev/docs/meshchatx_on_raspberry_pi.md"Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3MarkdownRendererTb4b4b4.Te6edf3stripTb4b4b4(Te6edf3urlTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Te6edf3urlTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"strip returns string for malformed and edge input"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3edge Tff7b72= Tb4b4b4[Ta5d6ff"**no close"Tb4b4b4, Ta5d6ff"```\ncode"Tb4b4b4, Ta5d6ff""Tb4b4b4, Ta5d6ff" "Tb4b4b4, Ta5d6ff"\n\n"Tb4b4b4, Ta5d6ff"[[CB0]] literal"Tb4b4b4]Tb4b4b4;
Te6edf3edgeTb4b4b4.Te6edf3forEachTb4b4b4(Tb4b4b4(Te6edf3sTb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3out Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3stripTb4b4b4(Te6edf3sTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Tff7b72typeof Te6edf3outTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff"string"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3describeTb4b4b4(Ta5d6ff"edge: non-string and invalid input"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3itTb4b4b4(Ta5d6ff"render does not throw on null or undefined"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3expectTb4b4b4(Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Tff7b72nullTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff""Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Tff7b72undefinedTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff""Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"render returns string for number input (coerced)"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3r Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(T79c0ff12345Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Tff7b72typeof Te6edf3rTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff"string"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3rTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"12345"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"render never returns executable script for any input"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3risky Tff7b72= Tb4b4b4[
Ta5d6ff"<script>alert(1)</script>"Tb4b4b4,
Ta5d6ff"javascript:alert(1)"Tb4b4b4,
Ta5d6ff"data:text/html,<script>alert(1)</script>"Tb4b4b4,
Ta5d6ff"'';alert(1);//"Tb4b4b4,
Tb4b4b4]Tb4b4b4;
Te6edf3riskyTb4b4b4.Te6edf3forEachTb4b4b4(Tb4b4b4(Te6edf3sTb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3r Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3sTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3rTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toMatchTb4b4b4(Ta5d6ff/<script[\s>]/iTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3rTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toMatchTb4b4b4(Ta5d6ff/\bhref\s*=\s*["']?\s*javascript:/iTb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3describeTb4b4b4(Ta5d6ff"edge: placeholder collision"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3itTb4b4b4(Ta5d6ff"literal [[CB0]] in text is not treated as code block placeholder"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3text Tff7b72= Ta5d6ff"See [[CB0]] and [[CB1]] here."Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"[[CB0]]"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"[[CB1]]"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"code block renders and restores; literal [[CB0]] may be replaced when code block exists"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3text Tff7b72= Ta5d6ff"Before ```\na\n``` after."Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"Before"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"after"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<pre"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3describeTb4b4b4(Ta5d6ff"message-like content (decoded LXMF body)"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3itTb4b4b4(Ta5d6ff"content with null byte and control chars does not crash"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3msg Tff7b72= Ta5d6ff"Hello\x00world\x07\n\t"Tb4b4b4;
Te6edf3expectTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3msgTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toThrowTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3r Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3msgTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Tff7b72typeof Te6edf3rTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff"string"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3rTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<script>"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"content with mixed unicode and markdown does not inject script"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3msg Tff7b72= Ta5d6ff"\u202eRTL **bold** <script>nope</script> \ufffd"Tb4b4b4;
Tff7b72const Te6edf3r Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3msgTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3rTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<script>"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3rTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"&lt;script&gt;"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"very long single-line message (100k chars) completes in reasonable time"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3msg Tff7b72= Ta5d6ff"x"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff100000Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3start Tff7b72= Tffa657DateTb4b4b4.Te6edf3nowTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3r Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3msgTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Tffa657DateTb4b4b4.Te6edf3nowTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3startTb4b4b4)Tb4b4b4.Te6edf3toBeLessThanTb4b4b4(T79c0ff500Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Tff7b72typeof Te6edf3rTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff"string"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"message with many newlines and markdown markers"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3msg Tff7b72= Ta5d6ff"# "Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff500Tb4b4b4) Tff7b72+ Ta5d6ff"**"Tb4b4b4.Te6edf3repeatTb4b4b4(T79c0ff500Tb4b4b4) Tff7b72+ Ta5d6ff"\n\n\n"Tb4b4b4;
Te6edf3expectTb4b4b4(Tb4b4b4(Tb4b4b4) Tb4b4b4=> Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3msgTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toThrowTb4b4b4(Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3r Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3msgTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Tff7b72typeof Te6edf3rTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff"string"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"renders a real-world mixed message body safely"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3msg Tff7b72= Tb4b4b4[
Ta5d6ff"# Deploy notes"Tb4b4b4,
Ta5d6ff""Tb4b4b4,
Ta5d6ff"Read https://github.com/Quad4-Software/MeshChatX/src/branch/dev/docs/meshchatx_on_raspberry_pi.md, then ping"Tb4b4b4,
Ta5d6ff"nomadnet://1dfeb0d794963579bd21ac8f153c77a4:/page/meshchatx_on_pi.mu"Tb4b4b4,
Ta5d6ff""Tb4b4b4,
Ta5d6ff"`inline_code` and _italic_ and snake_case stay sane."Tb4b4b4,
Ta5d6ff""Tb4b4b4,
Ta5d6ff"```txt"Tb4b4b4,
Ta5d6ff"https://example.com/not_linked_inside_code"Tb4b4b4,
Ta5d6ff"```"Tb4b4b4,
Tb4b4b4]Tb4b4b4.Te6edf3joinTb4b4b4(Ta5d6ff"\n"Tb4b4b4)Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderTb4b4b4(Te6edf3msgTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<h1"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(
Ta5d6ff'href="https://github.com/Quad4-Software/MeshChatX/src/branch/dev/docs/meshchatx_on_raspberry_pi.md"'
Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff'data-nomadnet-url="1dfeb0d794963579bd21ac8f153c77a4:/page/meshchatx_on_pi.mu"'Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<code"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<pre"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<em>case</em>"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3describeTb4b4b4(Ta5d6ff"renderBasic (RRC / limited chat markdown)"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Te6edf3itTb4b4b4(Ta5d6ff"renders bold, italic, strikethrough, and inline code"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderBasicTb4b4b4(Ta5d6ff"**bold** *italic* ~~gone~~ `code`"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<strong>bold</strong>"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<em>italic</em>"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<del>gone</del>"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<code"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"code"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"does not render headers or blockquotes"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderBasicTb4b4b4(Ta5d6ff"# Title\n> quote"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<h1"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"blockquote"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"# Title"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"keeps Nomad path field data after a single backtick as one link"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3text Tff7b72=
Ta5d6ff"9ce92808be498e9e05590ff27cbfdfe4:/page/forum/thread.mu`cat=general|thread=critical-security-update-rns-139-fixes-severe-rnsh-security-flaw"Tb4b4b4;
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderBasicTb4b4b4(Te6edf3textTb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"nomadnet-link"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(
Ta5d6ff'data-nomadnet-url="9ce92808be498e9e05590ff27cbfdfe4:/page/forum/thread.mu`cat=general|thread=critical-security-update-rns-139-fixes-severe-rnsh-security-flaw"'
Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<code"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"renders https links and escapes HTML"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderBasicTb4b4b4(Ta5d6ff"hi <script>alert(1)</script> https://example.com/a"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3notTb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"<script>"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff"&lt;script&gt;"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toContainTb4b4b4(Ta5d6ff'href="https://example.com/a"'Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;

Te6edf3itTb4b4b4(Ta5d6ff"preserves line breaks as br tags"Tb4b4b4, Tb4b4b4(Tb4b4b4) Tb4b4b4=> Tb4b4b4{
Tff7b72const Te6edf3result Tff7b72= Te6edf3MarkdownRendererTb4b4b4.Te6edf3renderBasicTb4b4b4(Ta5d6ff"line1\nline2"Tb4b4b4)Tb4b4b4;
Te6edf3expectTb4b4b4(Te6edf3resultTb4b4b4)Tb4b4b4.Te6edf3toBeTb4b4b4(Ta5d6ff"line1<br>line2"Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;
Tb4b4b4}Tb4b4b4)Tb4b4b4;


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────